-
Notifications
You must be signed in to change notification settings - Fork 17
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: support encoding and decoding of v1 shares #80
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good to me. One idea for further implementation: include signer in the commitment, so we can choose between 2 equal blobs posted by different signers
return &Blob{ | ||
namespace: ns, | ||
data: data, | ||
shareVersion: shareVersion, | ||
signer: signer, | ||
}, nil | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[not blocking]
is there a place with v0 and v1 blobs are documented? what do they contain and how they're constructed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Currently we just have this cip: https://github.com/celestiaorg/CIPs/blob/main/cips/cip-21.md
But it makes sense to definitely make sure the new blob type is clearly documented. I will need to think about where the best place for that is. We should probably have it mentioned in docs.celestia.org but perhaps we want to have a go.doc or readme.md in the code to explain it.
Will just jot this down as an issue so I don't forget
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note we have https://celestiaorg.github.io/celestia-app/specs/shares.html#share-version so it probably warrants a mention there (eventually)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point, I'll add it to the issue
name: "blob of one share with signer succeeds", | ||
namespace: ns1, | ||
blob: bytes.Repeat([]byte{0xFF}, shares.AvailableBytesFromSparseShares(2)-blob.SignerSize), | ||
expected: []byte{0x88, 0x3c, 0x74, 0x6, 0x4e, 0x8e, 0x26, 0x27, 0xad, 0x58, 0x8, 0x38, 0x9f, 0x1f, 0x19, 0x24, 0x19, 0x4c, 0x1a, 0xe2, 0x3c, 0x7d, 0xf9, 0x62, 0xc8, 0xd5, 0x6d, 0xf0, 0x62, 0xa9, 0x2b, 0x2b}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[not blocking]
how was this value generated? it would be great to have more information on how to generate the test values
if b == nil || !b.isFirstShare || b.shareVersion != ShareVersionOne { | ||
return | ||
} | ||
// NOTE: we don't check whether previous data has already been expected |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[nit]
I guess this note should also be written in the function docs so that users can see it when they're using it, instead of having to read the code to know
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think instead I want to make an assertion about the size of the rawShareData
before making the append to know whether the other writes have happened. Personally, I'm not sure about the entire builder struct (I think it should at least be private)
func NewShare(data []byte) (*Share, error) { | ||
if err := validateSize(data); err != nil { | ||
return nil, err | ||
} | ||
// TODO: we should also validate namespace |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should we create an issue for this?
func (s *Share) Len() int { | ||
return len(s.data) | ||
// Namespace returns the shares namespace | ||
// TODO: we could validate it the namespace in the constructor |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// TODO: we could validate it the namespace in the constructor | |
// TODO: we could validate the namespace in the constructor |
Also similar, do we need an issue for this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's the same issue just mentioned in two different places. I will create the issue. Thanks for reminding
// Blob (stands for binary large object) is a core type that represents data | ||
// to be submitted to the Celestia network alongside an accompanying namespace | ||
// and optional signer (for proving the signer of the blob) | ||
// and optional signer (for proving the author of the blob) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[nit] I think this was accidental b/c we renamed it to signer in a different PR
// and optional signer (for proving the author of the blob) | |
// and optional signer (for proving the signer of the blob) |
return nil, errors.New("share version 0 does not support signer") | ||
} | ||
if shareVersion == 1 && len(signer) != SignerSize { | ||
return nil, errors.New("share version 1 requires signer of size 20 bytes") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[optional] use the constant defined above
return nil, errors.New("share version 1 requires signer of size 20 bytes") | |
return nil, fmt.Errorf("share version 1 requires signer of size %d bytes", SignerSize) |
return &Blob{ | ||
namespace: ns, | ||
data: data, | ||
shareVersion: shareVersion, | ||
signer: signer, | ||
}, nil | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note we have https://celestiaorg.github.io/celestia-app/specs/shares.html#share-version so it probably warrants a mention there (eventually)
func NewV0(ns ns.Namespace, data []byte) *Blob { | ||
blob, err := New(ns, data, 0, nil) | ||
if err != nil { | ||
panic(err) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this panic kinda scares me. Can a malicious entity provide an invalid v0 namespace to an honest light node or consensus node and cause it to hit this panic? I think it is preferable to bubble up errors from low level code like this and let the application (celestia-app or celestia-node) decide what to do with the error if it encounters one.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Currently, the panic is not possible, because the namespace is encapsulated so we know it's valid and there's not a signer that could be of an invalid length. However since there could be changes in the future that could make errors acceptable, I think you're right and I will switch this to being an error
// SequenceLen returns the sequence length of this *share and optionally an | ||
// error. It returns 0, nil if this is a continuation share (i.e. doesn't | ||
// contain a sequence length). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
godoc needs updating.
// SequenceLen returns the sequence length of this *share and optionally an | |
// error. It returns 0, nil if this is a continuation share (i.e. doesn't | |
// contain a sequence length). | |
// SequenceLen returns the sequence length of this share. | |
// It returns 0 if this is a continuation share because then it doesn't contain a sequence length. |
@rootulp I will address your nits in a follow up PR (just so as to not block this) |
Closes: #86 This PR also addresses the nits from @Rootul's review [here](#80 (comment))
This adds the logic of encoding and decoding the signer bytes to the share (only for the first share in the sequence and only for v1 share versions).
Since we're encapsulating the types, many of the length checks can be removed and thus much data in the square does not need to return an error.